#!/bin/bash

################################################################################
# 脚本名称：find-all-used-ip-addr.sh
# 功能描述：
#   该脚本用于在本地局域网中查找已使用的 IP 地址。
#   提供四种扫描方法：ARP-scan、Netdiscover、Nmap 和 Ping 扫描。
#   每种方法都自动安装依赖工具，并进行扫描。
# 适用场景：
#   1. 快速发现局域网中的活动主机。
#   2. 网络管理和监控。
#   3. IP 冲突检测。
################################################################################

# => 获取脚本名称
ZN_SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})"

# => 获取脚本所在目录
ZN_SCRIPT_DIR="$(cd "$(dirname ${BASH_SOURCE[0]})" && pwd)"

# => 判断是否为 root 用户，不是则使用 sudo
[ "$(id -u)" -ne 0 ] && export SUDO="sudo" || export SUDO=""

# => 自动检测默认网络接口
default_iface=$(route | grep default | awk '{print $(NF); exit}')
echo "检测到默认网络接口：$default_iface"

# => 自动安装依赖工具的函数
install_package() {
    package="$1"
    if ! dpkg -s ${package} >/dev/null 2>&1; then
        echo "安装缺失的软件包：$package"
        ${SUDO} apt-get --assume-yes install ${package}
    fi
}

#####################################
# 方法一：ARP-scan
# 原理：
#   通过发送 ARP 请求来探测网络中的活跃主机。
#   适用于局域网扫描，速度快但只限于本地网络。
#####################################
arp_scan() {
    install_package "arp-scan"
    echo "正在使用 ARP-scan 扫描：$default_iface"
    ${SUDO} arp-scan -I ${default_iface} "$1" | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}"
}

#####################################
# 方法二：Netdiscover
# 原理：
#   通过 ARP 协议发现本地网络中的设备，适合无线和有线网络扫描。
#   被动模式（-P）确保扫描后自动退出。
#####################################
netdiscover_scan() {
    install_package "netdiscover"
    echo "正在使用 Netdiscover 扫描"
    ${SUDO} netdiscover -r "$1" -P
}

#####################################
# 方法三：Nmap
# 原理：
#   使用 Nmap 进行 Ping 扫描（-sn 选项），快速发现活动主机。
#   Nmap 是一款功能强大的网络扫描工具，支持多种扫描技术。
#####################################
nmap_scan() {
    install_package "nmap"
    echo "正在使用 Nmap 扫描"
    ${SUDO} nmap -sn "$1"
}

#####################################
# 方法四：Ping 扫描
# 原理：
#   使用 ping 命令逐个扫描网段中的 IP 地址。
#   逐个发送 ICMP 回显请求以判断主机是否在线，速度较慢。
#####################################
ping_sweep() {
    echo "正在使用 Ping 扫描"
    for ip in {1..254}; do
        base=$(echo "$1" | cut -d'/' -f1 | sed 's/\.[0-9]*$//')
        ping -c 1 -W 1 ${base}.$ip &>/dev/null && echo "192.168.30.$ip 在线"
    done
}

#####################################
# 主函数：依次测试每种扫描方法
main() {
    # 显示帮助信息
    if [[ "$1" == "-h" || "$1" == "--help" ]]; then
        echo "用法: $ZN_SCRIPT_NAME [网段]"
        echo "示例: $ZN_SCRIPT_NAME 192.168.1.0/24"
        echo "不指定网段时，默认扫描 192.168.30.0/24"
        exit 0
    fi

    # 读取命令行参数指定的网段，默认使用 192.168.30.0/24
    network_range="${1:-192.168.30.0/24}"
    echo "使用网段: $network_range"

    echo "正在测试 ARP-scan 方法："
    arp_scan "$network_range"
    echo
    echo "正在测试 Netdiscover 方法："
    netdiscover_scan "$network_range"
    echo
    echo "正在测试 Nmap 方法："
    nmap_scan "$network_range"
    echo
    echo "正在测试 Ping 扫描方法："
    ping_sweep "$network_range"
}

# => 执行主函数
main "$@"
